﻿using _80X_CG_Frame.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;

namespace _80X_CG_Frame.Protocols
{
    public class L02_MC_Class
    {
        private TcpClient client;
        private TcpClientWithTimeout tclient;
        private NetworkStream ns;
        static int maxBufferSize = 2144;
        static int timeout = 1000;
        private object obj = new object();

        public TcpClient Client
        {
            get
            {
                return client;
            }

            set
            {
                client = value;
            }
        }

        /// <summary>
        /// 连接PLC
        /// </summary>
        /// <param name="str">IP</param>
        /// <param name="port">端口号</param>
        /// <returns></returns>
        public async Task<bool> ConnectServer(string str, int port, int times)
        {
            if (Client == null || !IsConnect())
            {
                try
                {
                    /*
                    tclient = new TcpClientWithTimeout(str, port, timeout);
                    Client = tclient.Connect();
                    */
                    Client = new TcpClient();
                    client.ReceiveTimeout = 1000;
                    client.SendTimeout = 1000;
                    bool connected = await TcpAsyncConnect.ConnectAsync(Client, str, port, times);

                    if (Client.Connected)
                    {
                        ns = Client.GetStream();
                        ns.ReadTimeout = 100;
                        ns.WriteTimeout = 100;
                    }
                    return connected;
                }
                catch (Exception ex)
                {
                    //throw new Exception("PLC连接失败：" + ex.Message);
                    throw ex;
                }
            }
            return false;
        }

        public bool ConnectServer(string str, int port)
        {
            if (Client == null || !IsConnect())
            {
                try
                {
                    
                    tclient = new TcpClientWithTimeout(str, port, timeout);
                    Client = tclient.Connect();
                    /*
                    Client = new TcpClient();
                    client.ReceiveTimeout = 1000;
                    client.SendTimeout = 1000;
                    bool connected = tclient.c.ConnectAsync(Client, str, port, times);
                    */

                    if (Client.Connected)
                    {
                        ns = Client.GetStream();
                        ns.ReadTimeout = 100;
                        ns.WriteTimeout = 100;
                        return true;
                    }
                }
                catch (Exception ex)
                {
                    //throw new Exception("PLC连接失败：" + ex.Message);
                    System.Console.WriteLine("PLC连接失败：" + ex.Message);
                    //throw ex;
                    return false;
                }
            }
            return false;
        }

        /// <summary>
        /// PLC断开连接
        /// </summary>
        /// <returns></returns>
        public bool Close()
        {
            if (IsConnect())
            {
                if(ns != null)
                    ns.Close();
                if (client.Client != null)
                    client.Client.Close();
                Client.Close();
                //tclient.Connected = false;
            }
            return true;
        }


        /// <summary>
        /// 判断PLC是否连接成功
        /// </summary>
        /// <returns></returns>
        public bool IsConnect()
        {
            if (Client == null||Client.Client == null)
                return false;
            return Client.Connected && Client.Client.Connected;
        }


        /// <summary>
        /// Q&L系列PLC读位状态
        /// </summary>
        /// <param name="mname">寄存器标签</param>
        /// <param name="readMbitData">数据</param>
        /// <param name="blen">数据长度</param>
        /// <returns></returns>
        public bool ReadMbit(string mname, ref string readMbitData, string blen)
        {
            byte[] byteSend = new byte[maxBufferSize];
            byte[] byteReceive = new byte[maxBufferSize];
            string strAddress = mname.PadLeft(6, '0');
            string strLength = blen.PadLeft(4, '0');
            string result = "";
            string errcode = "";
            string readStrSend = "500000FF03FF000018001004010001M*" + strAddress + strLength;
            lock (obj)
            {
                byteSend = Encoding.ASCII.GetBytes(readStrSend);
                ns.Write(byteSend, 0, byteSend.Length);
                ns.Flush();
                //int count = 0;
                if (ns.CanRead)
                {
                    do
                    {
                        //count++;
                        int i = ns.Read(byteReceive, 0, maxBufferSize);

                        if (i > 0)
                            result = Encoding.ASCII.GetString(byteReceive, 0, i);
                    }
                    while (ns.DataAvailable);

                    if (!QLCheckEndCode(result, ref errcode))
                    {
                        return false;
                        //throw new Exception("读取PLC数据失败");
                    }

                    readMbitData = result.Substring(22);

                }

            }


            return true;
        }

        /// <summary>
        /// Q&L系列PLC写位状态
        /// </summary>
        /// <param name="mname">寄存器标签</param>
        /// <param name="writeMbitdData">数据</param>
        /// <returns></returns>
        public bool WriteMbit(string mname, string writeMbitdData)
        {
            byte[] byteSend = new byte[maxBufferSize];
            byte[] byteReceive = new byte[maxBufferSize];
            string strAddress = mname.PadLeft(6, '0');
            string strLength = "1".PadLeft(4, '0');
            string result = "";
            string valueString = writeMbitdData;
            string errcode = "";

            string writeStrSend = "500000FF03FF000019001014010001M*" + strAddress + strLength + valueString;
            //string writeStrSend = "02FF000A4D20000000F3010000";

            lock (obj)
            {
                byteSend = Encoding.ASCII.GetBytes(writeStrSend);
                //System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();

                //stopwatch.Start();
                ns.Write(byteSend, 0, byteSend.Length);
                ns.Flush();
                if (ns.CanRead)
                {
                    do
                    {
                        int i = ns.Read(byteReceive, 0, maxBufferSize);
                        if (i > 0)
                        {
                            result = Encoding.ASCII.GetString(byteReceive, 0, i);
                        }
                        else
                        {
                            //return false;
                            throw new Exception("PLC网络通讯端口已关闭");
                        }

                    }
                    while (ns.DataAvailable);

                    //stopwatch.Stop();
                    //MessageBox.Show(stopwatch.Elapsed.TotalSeconds.ToString());
                    if (!QLCheckEndCode(result, ref errcode))
                    {
                        return false;
                        //throw new Exception("写入数据失败！");
                    }

                }
            }
            return true;

        }

        /// <summary>
        /// Q&L系列PLC检查错误代码
        /// </summary>
        /// <param name="str"></param>
        /// <param name="err_code"></param>
        /// <returns></returns>
        public static bool QLCheckEndCode(string str, ref string err_code)
        {
            if (str == "")
                return false;
            string code = str.Substring(18, 4);

            if (code != "0000")
            {
                err_code = code;
                return false;
            }

            return true;
        }

        /// <summary>
        ///  Q&L系列PLC读字状态
        /// </summary>
        /// <param name="dname">寄存器标签</param>
        /// <param name="readDwordData">数据</param>
        /// <returns></returns>
        public bool ReadDword(string dname, ref int readDwordData)
        {

            byte[] byteSend = new byte[maxBufferSize];
            byte[] byteReceive = new byte[maxBufferSize];
            string strAddress = dname.PadLeft(6, '0');
            string result = "";
            string readStrSend = "500000FF03FF000018001004010000D*" + strAddress + "0002";

            lock (obj)
            {
                byteSend = Encoding.ASCII.GetBytes(readStrSend);
                ns.Write(byteSend, 0, byteSend.Length);
                ns.Flush();
                if (ns.CanRead)
                {
                    do
                    {
                        int i = ns.Read(byteReceive, 0, maxBufferSize);
                        if (i > 0)
                        {
                            result = Encoding.ASCII.GetString(byteReceive, 0, i);
                        }
                        else
                        {
                            //return false;
                            throw new Exception("PLC网络通讯端口已关闭！");
                        }


                    } while (ns.DataAvailable);

                    readDwordData = ReadDwordStrParse(result);

                }

            }


            return true;
        }

        /// <summary>
        /// Q&L系列PLC写位状态
        /// </summary>
        /// <param name="dname">寄存器标签</param>
        /// <param name="writeDwordData">数据</param>
        /// <returns></returns>
        public bool WriteDword(string dname, ref int writeDwordData)
        {
            byte[] byteSend = new byte[maxBufferSize];
            byte[] byteReceive = new byte[maxBufferSize];
            string strAddress = dname.PadLeft(6, '0');
            string result = "";
            string valueString = ConvertToDword(writeDwordData);

            string writeStrSend = "500000FF03FF000020001014010000D*" + strAddress + "0002" + valueString;
            lock (obj)
            {
                byteSend = Encoding.ASCII.GetBytes(writeStrSend);
                ns.Write(byteSend, 0, byteSend.Length);
                ns.Flush();
                if (ns.CanRead)
                {
                    do
                    {
                        int i = ns.Read(byteReceive, 0, maxBufferSize);
                        if (i > 0)
                        {
                            result = Encoding.ASCII.GetString(byteReceive, 0, i);
                        }
                        else
                        {
                            //return false;
                            throw new Exception("PLC网络通讯端口已关闭");
                        }

                    } while (ns.DataAvailable);

                    if (!WriteDwordStrParse(result))
                    {
                        // return false;
                        throw new Exception("写入数据失败");
                    }

                }
            }

            return true;

        }

        /// <summary>
        /// FX-3U系列PLC读位状态
        /// </summary>
        /// <param name="mname">寄存器标签</param>
        /// <param name="readMbitData">数据</param>
        /// <param name="blen">数据长度</param>
        /// <returns></returns>
        public bool FXReadMbit(string mname, ref string readMbitData, string blen)
        {
            byte[] byteSend = new byte[maxBufferSize];
            byte[] byteReceive = new byte[maxBufferSize];
            string strAddress = Convert.ToInt32(mname).ToString("X8");
            string strLength = Convert.ToInt32(blen).ToString("X2");
            string result = "";
            string readStrSend = "00FF00014D20" + strAddress + strLength + "00";
            //string readStrSend = "00FF00014D20000000F30100";
            lock (obj)
            {
                byteSend = Encoding.ASCII.GetBytes(readStrSend);
                ns.Write(byteSend, 0, byteSend.Length);
                ns.Flush();
                int count = 0;
                if (ns.CanRead)
                {
                    do
                    {
                        count++;
                        int i = ns.Read(byteReceive, 0, maxBufferSize);

                        if (i > 0)
                        {
                            result = Encoding.ASCII.GetString(byteReceive, 0, i);
                        }
                        else
                        {
                            //return false;
                            throw new Exception("PLC网络通讯端口已关闭");
                        }


                    } while (ns.DataAvailable);

                    if (!FXCheckEndCode(result))
                    {
                        return false;
                        //throw new Exception("读数据失败");
                    }

                    readMbitData = result.Substring(4);

                }
            }


            return true;
        }

        /// <summary>
        /// FX-3U系列PLC写位状态
        /// </summary>
        /// <param name="mname">寄存器标签</param>
        /// <param name="writeMbitdData">数据</param>
        /// <returns></returns>
        public bool FXWriteMbit(string mname, string writeMbitdData)
        {

            byte[] byteSend = new byte[maxBufferSize];
            byte[] byteReceive = new byte[maxBufferSize];
            string strAddress = Convert.ToInt32(mname).ToString("X8");
            //string strLength = 1.ToString("X2");
            string result = "";
            string valueString = writeMbitdData.PadRight(2, '0');

            string writeStrSend = "02FF00014D20" + strAddress + "0100" + valueString;
            //string writeStrSend = "02FF000A4D20000000F3010000";
            lock (obj)
            {
                byteSend = Encoding.ASCII.GetBytes(writeStrSend);
                //System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();

                //stopwatch.Start();
                ns.Write(byteSend, 0, byteSend.Length);
                ns.Flush();
                if (ns.CanRead)
                {
                    do
                    {
                        int i = ns.Read(byteReceive, 0, maxBufferSize);
                        if (i > 0)
                        {
                            result = Encoding.ASCII.GetString(byteReceive, 0, i);
                        }
                        else
                        {
                            //return false;
                            throw new Exception("PLC网络通讯端口已关闭");
                        }

                    } while (ns.DataAvailable);

                    if (!FXCheckEndCode(result))
                    {
                        return false;
                        //throw new Exception("写入数据失败");
                    }
                }
            }

            return true;

        }

        /// <summary>
        ///  FX系列PLC检查错误代码
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static bool FXCheckEndCode(string str)
        {
            string code = str.Substring(0, 4);
            if (code == "8000" || code == "8200")
            {
                return true;
            }

            return false;

        }

        /// <summary>
        /// Q&L系列PLC读位状态
        /// </summary>
        /// <param name="mname">寄存器标签</param>
        /// <param name="readMbitData">数据</param>
        /// <param name="blen">数据长度</param>
        /// <returns></returns>
        public bool BinReadMbit(string mname, ref string readMbitData, string blen)
        {

            byte[] byteSend = new byte[maxBufferSize];
            byte[] byteReceive = new byte[maxBufferSize];
            string strAddress = Convert.ToInt32(mname).ToString("X6");
            string strLength = Convert.ToInt32(blen).ToString("X4");
            string result = "";
            string errcode = "";

            string readStrSend = "500000FFFF03000C00100001040100" + ConvertBinLH(strAddress) + "90" + ConvertBinLH(strLength);
            lock (obj)
            {
                try
                {
                    byteSend = ConvertBytes(readStrSend);
                    ns.Write(byteSend, 0, byteSend.Length);
                    ns.Flush();

                    if (ns.CanRead)
                    {
                        do
                        {
                            int i = ns.Read(byteReceive, 0, maxBufferSize);

                            if (i > 0)
                            {
                                result = ConvertString(byteReceive, i);
                            }
                            else
                            {
                                //throw new Exception("PLC网络通讯端口已关闭");
                                return false;
                            }

                        } while (ns.DataAvailable);

                        if (!QLCheckEndCode(result, ref errcode))
                        {
                            //throw new Exception("读取PLC数据失败");
                            return false;
                        }

                        readMbitData = result.Substring(22, Int32.Parse(blen));

                    }

                }
                catch (ObjectDisposedException ex)
                {
                    //throw new Exception(ex.ToString());
                    return false;
                }
            }


            return true;
        }

        /// <summary>
        /// Q&L系列PLC写位状态
        /// </summary>
        /// <param name="mname">寄存器标签</param>
        /// <param name="writeMbitdData">数据</param>
        /// <returns></returns>
        public bool BinWriteMbit(string mname, string writeMbitdData)
        {

            byte[] byteSend = new byte[maxBufferSize];
            byte[] byteReceive = new byte[maxBufferSize];
            string strAddress = Convert.ToInt32(mname).ToString("X6");// PadLeft(6, '0');
            string strLength = "1".PadLeft(4, '0');
            string result = "";
            string valueString = writeMbitdData.PadRight(2, '0');
            string errcode = "";


            string writeStrSend = "500000FFFF03000D00100001140100" + ConvertBinLH(strAddress) + "90" + ConvertBinLH(strLength) + valueString;
            {
                try
                {
                    byteSend = ConvertBytes(writeStrSend);
                    //System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();

                    //stopwatch.Start();
                    lock (obj)
                    {
                        ns.Write(byteSend, 0, byteSend.Length);
                        ns.Flush();
                        if (ns.CanRead)
                        {
                            do
                            {
                                int i = ns.Read(byteReceive, 0, maxBufferSize);
                                if (i > 0)
                                {
                                    result = ConvertString(byteReceive, i);
                                }
                                else
                                {
                                    throw new Exception("PLC网络通讯端口已关闭");
                                    //return false;
                                }

                            } while (ns.DataAvailable);

                            //stopwatch.Stop();
                            //MessageBox.Show(stopwatch.Elapsed.TotalSeconds.ToString());
                            if (!QLCheckEndCode(result, ref errcode))
                            {
                                throw new Exception("写入数据失败！");
                                //return false;
                            }

                        }
                    }

                }
                catch (Exception ex)
                {
                    throw new Exception(ex.ToString());
                    //return false;

                }
            }

            return true;

        }


        /// <summary>
        /// FX-3U系列PLC读位状态
        /// </summary>
        /// <param name="mname">寄存器标签</param>
        /// <param name="readMbitData">数据</param>
        /// <param name="blen">数据长度</param>
        /// <returns></returns>
        public bool BinFXReadMbit(string mname, ref string readMbitData, string blen)
        {

            byte[] byteSend = new byte[maxBufferSize];
            byte[] byteReceive = new byte[maxBufferSize];
            string strAddress = Convert.ToInt32(mname).ToString("X8");
            string strLength = Convert.ToInt32(blen).ToString("X2");
            string result = "";
            //string readStrSend = "00FF00014D20" + strAddress + strLength + "00";
            string readStrSend = "00FF0100" + ConvertBinLH(strAddress) + "204D" + strLength + "00";
            //string readStrSend = "00FF00014D20000000F30100";
            lock (obj)
            {
                try
                {
                    System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();

                    byteSend = Encoding.UTF8.GetBytes(readStrSend);

                    byteSend = ConvertBytes(readStrSend);
                    ns.Write(byteSend, 0, byteSend.Length);
                    ns.Flush();
                    if (ns.CanRead)
                    {
                        do
                        {
                            int i = ns.Read(byteReceive, 0, maxBufferSize);

                            if (i > 0)
                            {
                                result = ConvertString(byteReceive, i);
                            }
                            else
                            {
                                throw new Exception("PLC网络通讯端口已关闭");
                                //return false;
                            }


                        } while (ns.DataAvailable);

                        if (!FXCheckEndCode(result))
                        {
                            throw new Exception("读数据失败！");
                            //return false;
                        }

                        readMbitData = result.Substring(4);

                    }

                }
                catch (Exception ex)
                {
                    throw new Exception(ex.ToString());
                    //return false;

                }
            }


            return true;
        }

        /// <summary>
        /// FX-3U系列PLC写位状态
        /// </summary>
        /// <param name="mname">寄存器标签</param>
        /// <param name="writeMbitdData">数据</param>
        /// <returns></returns>
        public bool BinFXWriteMbit(string mname, string writeMbitdData)
        {

            byte[] byteSend = new byte[maxBufferSize];
            byte[] byteReceive = new byte[maxBufferSize];
            string strAddress = Convert.ToInt32(mname).ToString("X8");
            //string strLength = 1.ToString("X2");
            string result = "";
            string valueString = writeMbitdData.PadRight(2, '0');
            string writeStrSend = "02FF0100" + ConvertBinLH(strAddress) + "204D" + "0100" + valueString;

            //string writeStrSend = "02FF00014D20" + strAddress + "0100"+ valueString;
            //string writeStrSend = "02FF000A4D20000000F3010000";
            {
                try
                {
                    //byteSend = Encoding.ASCII.GetBytes(writeStrSend);
                    //System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
                    byteSend = ConvertBytes(writeStrSend);
                    //stopwatch.Start();
                    lock (obj)
                    {
                        ns.Write(byteSend, 0, byteSend.Length);
                        ns.Flush();
                        if (ns.CanRead)
                        {
                            do
                            {
                                int i = ns.Read(byteReceive, 0, maxBufferSize);
                                if (i > 0)
                                {
                                    result = ConvertString(byteReceive, i);
                                }
                                else
                                {
                                    throw new Exception("PLC网络通讯端口已关闭");
                                    //return false;
                                }

                            } while (ns.DataAvailable);

                            if (!FXCheckEndCode(result))
                            {
                                throw new Exception("写入数据失败！");
                                //return false;
                            }

                        }
                    }

                }
                catch (Exception ex)
                {
                    throw new Exception(ex.ToString());
                    //return false;

                }
            }

            return true;

        }

        /// <summary>
        ///  Q&L系列PLC读双字状态
        /// </summary>
        /// <param name="dname">寄存器标签</param>
        /// <param name="readDwordData">数据</param>
        /// <returns></returns>
        public bool BinReadDword(string dname, ref int readDwordData)
        {

            if (client == null || !client.Connected)
            {
                //throw new Exception("未连接PLC，请先进行PLC连接");
                return false;
            }



            if (!IsNumeric(dname))
            {
                //MessageBox.Show("请输入正确的寄存器地址格式,十进制数字字符串", "读取PLC数据失败提示：");
                return false;
            }

            int dword = 2;
            byte[] byteSend = new byte[maxBufferSize];
            byte[] byteReceive = new byte[maxBufferSize];
            string strAddress = Convert.ToInt32(dname).ToString("X6");
            string strLength = Convert.ToInt32(dword).ToString("X4");
            string result = "";
            string errcode = "";

            string readStrSend = "500000FFFF03000C00100001040000" + ConvertBinLH(strAddress) + "A8" + ConvertBinLH(strLength);
            lock (obj)
            {
                try
                {

                    byteSend = ConvertBytes(readStrSend);
                    ns.Write(byteSend, 0, byteSend.Length);
                    ns.Flush();
                    if (ns.CanRead)
                    {
                        do
                        {
                            int i = ns.Read(byteReceive, 0, maxBufferSize);
                            if (i > 0)
                            {
                                result = ConvertString(byteReceive, i);
                            }
                            else
                            {
                                //MessageBox.Show("PLC网络通讯端口已关闭", "读取PLC数据失败提示：");
                                return false;
                            }


                        } while (ns.DataAvailable);

                        if (!QLCheckEndCode(result, ref errcode))
                        {
                            //MessageBox.Show("读取PLC数据失败", "读取PLC数据失败提示：");
                            return false;
                        }


                        readDwordData = ReadDword(result);

                    }

                }
                catch (Exception ex)
                {
                    //MessageBox.Show(ex.ToString(), "读取PLC数据失败提示：");
                    return false;

                }
            }


            return true;
        }

        /// <summary>
        /// Q&L系列PLC写双字状态
        /// </summary>
        /// <param name="dname">寄存器标签</param>
        /// <param name="writeDwordData">数据</param>
        /// <returns></returns>
        public bool BinWriteDword(string dname, int writeDwordData)
        {


            if (client == null || !client.Connected)
            {
                //MessageBox.Show("未连接PLC，请先进行PLC连接", "写入PLC数据失败提示：");
                return false;
            }


            if (!IsNumeric(dname))
            {
                //MessageBox.Show("请输入正确的寄存器地址格式,十进制数字字符串", "写入PLC数据失败提示：");
                return false;
            }


            byte[] byteSend = new byte[maxBufferSize];
            byte[] byteReceive = new byte[maxBufferSize];
            string strAddress = Convert.ToInt32(dname).ToString("X6");// PadLeft(6, '0');
            string strLength = "2".PadLeft(4, '0');
            string valueString = ConvertBinLH(IntToStr8(writeDwordData));
            string errcode = "";
            string result = "";

            string writeStrSend = "500000FFFF03001000100001140000" + ConvertBinLH(strAddress) + "A8" + ConvertBinLH(strLength) + valueString;
            {
                lock (obj)
                {
                    try
                    {
                        byteSend = ConvertBytes(writeStrSend);
                        ns.Write(byteSend, 0, byteSend.Length);
                        ns.Flush();
                        if (ns.CanRead)
                        {
                            do
                            {
                                int i = ns.Read(byteReceive, 0, maxBufferSize);
                                if (i > 0)
                                {
                                    result = ConvertString(byteReceive, i);
                                }
                                else
                                {
                                    //MessageBox.Show("PLC网络通讯端口已关闭", "写入PLC数据失败提示：");
                                    return false;
                                }

                            } while (ns.DataAvailable);

                            if (!QLCheckEndCode(result, ref errcode))
                            {
                                //MessageBox.Show("写入数据失败！", "写入PLC数据失败提示：");
                                return false;
                            }

                        }

                    }
                    catch (Exception ex)
                    {
                        //MessageBox.Show(ex.ToString(), "写入PLC数据失败提示：");
                        return false;

                    }
                }
            }

            return true;

        }
        /// <summary>
        /// Q&L系列PLC读双字
        /// </summary>
        /// <param name="dname">寄存器标签</param>
        /// <param name="writeDwordData">数据(浮点型)</param>
        /// <returns></returns>
        public bool BinReadDword(string dname, ref float readDwordData)
        {

            if (client == null || !client.Connected)
            {
                //MessageBox.Show("未连接PLC，请先进行PLC连接", "读取PLC数据失败提示：");
                return false;
            }



            if (!IsNumeric(dname))
            {
                //MessageBox.Show("请输入正确的寄存器地址格式,十进制数字字符串", "读取PLC数据失败提示：");
                return false;
            }

            int dword = 2;
            byte[] byteSend = new byte[maxBufferSize];
            byte[] byteReceive = new byte[maxBufferSize];
            string strAddress = Convert.ToInt32(dname).ToString("X6");
            string strLength = Convert.ToInt32(dword).ToString("X4");
            string result = "";
            string errcode = "";

            string readStrSend = "500000FFFF03000C00100001040000" + ConvertBinLH(strAddress) + "A8" + ConvertBinLH(strLength);
            lock (obj)
            {
                try
                {

                    byteSend = ConvertBytes(readStrSend);
                    ns.Write(byteSend, 0, byteSend.Length);
                    ns.Flush();
                    if (ns.CanRead)
                    {
                        do
                        {
                            int i = ns.Read(byteReceive, 0, maxBufferSize);
                            if (i > 0)
                            {
                                result = ConvertString(byteReceive, i);
                            }
                            else
                            {
                                //MessageBox.Show("PLC网络通讯端口已关闭", "读取PLC数据失败提示：");
                                return false;
                            }


                        } while (ns.DataAvailable);

                        if (!QLCheckEndCode(result, ref errcode))
                        {
                            //MessageBox.Show("读取PLC数据失败", "读取PLC数据失败提示：");
                            return false;
                        }


                        readDwordData = ReadDwordFloat(result);

                    }

                }
                catch (Exception ex)
                {
                    //MessageBox.Show(ex.ToString(), "读取PLC数据失败提示：");
                    return false;

                }
            }


            return true;
        }

        /// <summary>
        /// Q&L系列PLC写双字
        /// </summary>
        /// <param name="dname">寄存器标签</param>
        /// <param name="writeDwordData">数据(浮点型)</param>
        /// <returns></returns>
        public bool BinWriteDword(string dname, float writeDwordData)
        {


            if (client == null || !client.Connected)
            {
                //MessageBox.Show("未连接PLC，请先进行PLC连接", "写入PLC数据失败提示：");
                return false;
            }


            if (!IsNumeric(dname))
            {
                //MessageBox.Show("请输入正确的寄存器地址格式,十进制数字字符串", "写入PLC数据失败提示：");
                return false;
            }


            byte[] byteSend = new byte[maxBufferSize];
            byte[] byteReceive = new byte[maxBufferSize];
            string strAddress = Convert.ToInt32(dname).ToString("X6");// PadLeft(6, '0');
            string strLength = "2".PadLeft(4, '0');

            string valueString = ConvertBinLH(FloatToStr8(writeDwordData));

            string errcode = "";
            string result = "";

            string writeStrSend = "500000FFFF03001000100001140000" + ConvertBinLH(strAddress) + "A8" + ConvertBinLH(strLength) + valueString;
            {
                try
                {
                    byteSend = ConvertBytes(writeStrSend);
                    ns.Write(byteSend, 0, byteSend.Length);
                    ns.Flush();
                    if (ns.CanRead)
                    {
                        do
                        {
                            int i = ns.Read(byteReceive, 0, maxBufferSize);
                            if (i > 0)
                            {
                                result = ConvertString(byteReceive, i);
                            }
                            else
                            {
                                //MessageBox.Show("PLC网络通讯端口已关闭", "写入PLC数据失败提示：");
                                return false;
                            }

                        } while (ns.DataAvailable);

                        if (!QLCheckEndCode(result, ref errcode))
                        {
                            //MessageBox.Show("写入数据失败！", "写入PLC数据失败提示：");
                            return false;
                        }

                    }

                }
                catch (Exception ex)
                {
                    //MessageBox.Show(ex.ToString(), "写入PLC数据失败提示：");
                    return false;

                }
            }

            return true;

        }

        public static string ConvertBinLH(string str)
        {
            string s = "";
            for (int i = str.Length - 2; i >= 0; i -= 2)
            {
                s += str.Substring(i, 2);
            }

            return s;
        }

        public static byte[] ConvertBytes(string str)
        {
            byte[] code = new byte[str.Length / 2];

            for (int i = 0; i < str.Length; i += 2)
            {
                code[i / 2] = Convert.ToByte(str.Substring(i, 2), 16);
            }

            return code;

        }

        public static string ConvertString(byte[] code, int len)
        {
            string s = "";
            for (int i = 0; i < len; i++)
            {
                s += code[i].ToString("X2");
            }

            return s;
        }


        public static bool IsNumeric(string s)
        {
            int v;
            if (Int32.TryParse(s, out v))
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        #region 字相关转换函数
        public static float ReadDwordFloat(string str)
        {
            string str_temp = str.Substring(22);

            float value = Str8ToFloat(str_temp);

            return value;

        }

        public static string FloatToStr8(float ft)
        {
            Byte[] bs = BitConverter.GetBytes(ft);
            string result = "";
            for (int i = bs.Length - 1; i >= 0; i--)
            {
                result += bs[i].ToString("X2");
            }

            return result;

        }
        public static float Str8ToFloat(string str)
        {
            float fvalue;
            //string svalue = ConvertBinLH(str);
            string svalue = str;

            byte[] bvalue = new byte[4];

            bvalue = ConvertBytes(svalue);

            fvalue = BitConverter.ToSingle(bvalue, 0);
            //int s66 = BitConverter.ToInt32(bvalue, 0);

            return (float)Math.Round(fvalue, 0);
        }
        public static int Str8ToInt(string str)
        {
            int value;
            //string svalue = ConvertBinLH(str);
            string svalue = str;

            byte[] bvalue = new byte[4];

            bvalue = ConvertBytes(svalue);

            value = BitConverter.ToInt32(bvalue, 0);

            return value;
        }

        public static int ReadDword(string str)
        {
            string str_temp = str.Substring(22);

            int value = Str8ToInt(str_temp);

            return value;

        }
        
        public string IntToStr8(int ft)
        {
            Byte[] bs = BitConverter.GetBytes(ft);
            string result = "";
            for (int i = bs.Length - 1; i >= 0; i--)
            {
                result += bs[i].ToString("X2");
            }

            return result;

        }

        public static int Str8ToInt32(string str)
        {
            int i;
            string str_temp_low;
            string str_temp_high;

            str_temp_low = str.Substring(0, 4);
            str_temp_high = str.Substring(4, 4);

            short st_low = Convert.ToInt16(str_temp_low, 16);
            short st_high = Convert.ToInt16(str_temp_high, 16);


            i = st_high * 65536 + (ushort)st_low;

            return i;
        }


        //int转换为 4 HEX   string  
        public static string ConvertToDword(int i)
        {
            byte[] bt = BitConverter.GetBytes(i);
            short st3 = BitConverter.ToInt16(bt, 0);
            short st4 = BitConverter.ToInt16(bt, 2);
            string str3 = Convert.ToString(st3, 16);
            string str4 = Convert.ToString(st4, 16);
            string str5 = str3.PadLeft(4, '0');
            string str6 = str4.PadLeft(4, '0');
            return str5 + str6;
        }

        public static int ReadDwordStrParse(string str)
        {
            string str_temp = str.Substring(22);

            return Str8ToInt32(str_temp);

        }

        public static bool WriteDwordStrParse(string str)
        {

            if (str.Length == 22)
            {
                return true;
            }
            else
            {
                //MessageBox.Show("写入数据失败！！！", "写入PLC数据失败提示：");
                return false;
            }



        }


        #endregion


        public void ReceiveDataParse(string str, int Length)
        {
            //先判断字符长度是否固定
            string strTmp = str;
            string str_D0 = "", str_D1 = "", str_D2 = "", str_D3 = "", str_D4 = "", str_D5 = "", str_D6 = "", str_D7 = "", str_D10 = "";

            if (Length < 24)
                return;
            //AscII 读取响应单字             D1800---D1807
            //D000 00FF 03FF 0000 2400 00 0001 0002 0003 0004 0005 0006 0007  0008
            if (Length == 54)
            {
                strTmp = strTmp.Substring(22);  //截去前面22位
                str_D0 = strTmp.Substring(0, 4);
                str_D1 = strTmp.Substring(4, 4);
                str_D2 = strTmp.Substring(8, 4);
                str_D3 = strTmp.Substring(12, 4);
                str_D4 = strTmp.Substring(16, 4);
            }
        }

        public string SenddataConvert(string[] strArr)
        {
            //string[] strArray;
            string strRet = "500000FF03FF000030001014010000D*0018020006";   //从1802开始发
            string X_Offset, Y_Offset, A_Offset;
            X_Offset = (Convert.ToDouble(strArr[0]) * 100).ToString("f0");    //确保不会溢出
            Y_Offset = (Convert.ToDouble(strArr[1]) * 100).ToString("f0");
            A_Offset = (Convert.ToDouble(strArr[2]) * 125000 / 360).ToString("f0"); //发送脉冲数


            short st1 = Convert.ToInt16(X_Offset, 10);    //D1802
            short st2 = Convert.ToInt16(Y_Offset, 10);    //D1804
            short st3 = Convert.ToInt16(A_Offset, 10);    //D1806


            X_Offset = ConvertToDword((int)st1);
            Y_Offset = ConvertToDword((int)st2);
            A_Offset = ConvertToDword((int)st3);

            strRet = strRet + X_Offset + Y_Offset + A_Offset;   //1803 1805 1807 直接填0
            return strRet;
        }
    }
}
